package Config;

/**
 *
 * La classe Data fournit deux services destines a simplifier la gestion des 
 * fichiers de donnees.
 *
 * Les services fournis sont :
 *
 * load   : charger un objet depuis le repertoire courant ou depuis le
 *          sous repertoire Data
 * store  : enregistrer un objet dans le repertoire courant.
 * 
 * Version 1.0.0  : version initiale
 * 
 * Version 1.1.0  : avec trace de l'execution d'un service dans la console
 * 
 * Version 1.2.0  : chargement d'un fichier de donnees depuis le sous
 *                  repertoire Data du repertoire courant, a defaut de le
 *                  trouver directement dans ce dernier   
 *                  
 * Version 2.0.0  : - reecriture plus propre du code (de l'indendation 
 *                    principalement
 *                  - si la version n'est pas renseigne, on prendra non
 *                    pas un fichier "fichier-.data", mais un fichier
 *                    "fichier.data" (sans le tiret)
 *                    
 * Version 2.1.0  : - methode "storeXML" et "loadXML" pour serialiser un objet 
 *                    au format XML a l'aide de java.beans
 *                    
 * Version 2.2.0 : - ajoute des surcharges de store et load sans le parametre 
 *                   "version"
 */

import java.beans.DefaultPersistenceDelegate;
import java.beans.PersistenceDelegate;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

abstract public class Data
{
	/**
	 * La methode store enregistre dans un fichier du repertoire courant 
	 * l'objet fourni en premier parametre.
	 * Le fichier resultant est cree avec l'extension .data. 
	 * Le nom du fichier est forme automatiquement de la facon suivante : 
	 * p2-p3.data, ou p2 et p3 designent les deux derniers parametres effectifs. 
	 */
	public static boolean store(Object data, String name, String version)
	{                          	
		String nomFichier = "";      
		FileOutputStream f = null;
		ObjectOutputStream out = null;
   
		// Controler l'existence de la donnee
		//
		if (data == null) return false;
  
		// Construire le nom du fichier de donnees
		//
		if (version == null || version.equals(""))
			nomFichier = name + ".data";
		else
			nomFichier = name + "-" + version + ".data";
  
		try{
			// Construire un fichier logique et le fichier physique associe
			//
			f = new FileOutputStream(nomFichier);
  
			// Construire un flux de sortie base sur le fichier logique
			//
			out= new ObjectOutputStream(f);
  
			// Serialiser l'objet contenant les donnees dans le flux de sortie
			//
			out.writeObject(data);
		}
		catch (Exception e) {return false;}
  
		System.out.println("Enregistrement du fichier " + nomFichier + " : OK");
		return true;
	}
	
	public static boolean store(Object data, String name)
	{
	    return store(data, name, null);
	}
   
	/**
	 * La methode load charge le contenu d'un fichier de donnees 
	 *                                            depuis le repertoire courant 
	 * ou a defaut depuis le sous repertoire Data.
	 * L'objet resultant est la valeur de retour. 
	 * Le fichier origine possede obligatoirement l'extension .data. 
	 * Le nom du fichier est forme automatiquement de la facon suivante : 
	 * p1-p2.data, ou p1 et p2 designent les deux parametres effectifs. 
	 */

	public static Object load (String name, String version)
	{
		String nomFichier = "";      
		FileInputStream f = null;
		ObjectInputStream in = null;
		Object resultat = null;
   
		// Construire le nom du fichier source des donnees
		//
		if (version == null || version.equals(""))
			nomFichier = name + ".data";
		else
			nomFichier = name + "-" + version + ".data";     
 
		try{
			// Construire un fichier logique correspondant
			//
			try {
				f= new FileInputStream(nomFichier);
			}
			catch (Exception e1) {
				nomFichier= "Data/" + nomFichier;
				f= new FileInputStream(nomFichier);
			}
			// Construire un flux d'entree base sur le fichier logique
			//
			in= new ObjectInputStream(f);	
      
			// Acquerir et deserialiser le flux d'entree
			//
			resultat=in.readObject();
		}
		catch (Exception e) { return null; }
          
		System.out.println("Chargement du fichier " + nomFichier + " : OK");
		return resultat;
   }
	
	public static Object load (String name)
	{
	    return load(name, null);
	}
    
    public static boolean storeXML(Object data, String name)
    {
        return storeXML(data, name, null);
    }
    
	public static boolean storeXML(Object data, String name, String version)
	{
	    return storeXML(data, name, version, new DefaultPersistenceDelegate());
	}
	
	public static boolean storeXML(Object data, String name, String version, 
	                                                    PersistenceDelegate pd)
	{
        String nomFichier = "";      
        FileOutputStream f = null;
        BufferedOutputStream out = null;

        if (data == null) return false;
  
        if (version == null || version.equals(""))
            nomFichier = name + ".xml";
        else
            nomFichier = name + "-" + version + ".xml";
  
        try
        {
            f = new FileOutputStream(nomFichier);

            out = new BufferedOutputStream(f);
  
            XMLEncoder encoder = new XMLEncoder(out);
            
            encoder.setPersistenceDelegate(data.getClass(), pd);
            
            encoder.writeObject(data);
            
            encoder.close();
        }
        catch (Exception e)
        {
            return false;
        }
  
        System.out.println("Enregistrement du fichier " + nomFichier + " : OK");
        return true;
	}
	
	public static Object loadXML(String name, String version)
	{
        String nomFichier = "";      
        FileInputStream f = null;
        Object resultat = null;
   
        if (version == null || version.equals(""))
            nomFichier = name + ".xml";
        else
            nomFichier = name + "-" + version + ".xml";     
 
        try
        {
            f = new FileInputStream(nomFichier);

            XMLDecoder decoder = new XMLDecoder(f);
            
            resultat = decoder.readObject();
            
            decoder.close();
        }
        catch (Exception e)
        {
            return null;
        }
          
        System.out.println("Chargement du fichier " + nomFichier + " : OK");
        return resultat;
	}
	
	public static Object loadXML(String name)
	{
	    return loadXML(name, null);
	}
}
